package idvis

import (
	"fmt"
	"math/rand"
	"regexp"
	"strconv"
	"strings"
	"time"
)

type IdNumber struct {
	Id        string
	AreaId    string
	BirthYear string
	BirthMoth string
	BirthDay  string
}

var IdCard IdNumber

func (o *IdNumber) Init(idNumber string) *IdNumber {
	idNumber = strings.ToUpper(idNumber)
	o.Id = idNumber
	o.AreaId = idNumber[:6]
	o.BirthYear = idNumber[6:10]
	o.BirthMoth = idNumber[10:12]
	o.BirthDay = idNumber[12:14]
	return o
}
func (o *IdNumber) GetAreaName() string {
	return AREA_INFO[o.AreaId]
} //根据区域编号取出区域名称
func (o *IdNumber) GetBirthDay() string {
	return fmt.Sprintf(`%s-%s-%s`, o.BirthYear, o.BirthMoth, o.BirthDay)
} //通过身份证号获取出生日期
func (o *IdNumber) GetAge() int {
	y, _ := strconv.Atoi(o.BirthYear)
	return time.Now().Year() - y
} //通过身份证号获取年龄

func (o *IdNumber) GetSex() int {
	y, _ := strconv.Atoi(o.Id[16:17])
	return y % 2
} //通过身份证号获取性别， 女生：0，男生：1
func (o *IdNumber) GetCheckDigit() string {
	checkSum := 0
	for i := 0; i < 17; i++ {
		v, _ := strconv.Atoi(o.Id[i : i+1])
		checkSum += ((1 << (17 - i)) % 11) * v
	}
	checkDigit := (12 - (checkSum % 11)) % 11
	if checkDigit < 10 {
		return strconv.Itoa(checkDigit)
	} else {
		return "X"
	}
} //通过身份证号获取校验码
func (o *IdNumber) VerifyId(idNumber string) (is bool) {
	defer func() {
		if r := recover(); r != nil {
			is = false
			return
		}
	}()
	o.Init(idNumber)
	if _, is := AREA_INFO[o.AreaId]; !is {
		return false
	}
	if regexp.MustCompile(ID_NUMBER_18_REGEX).MatchString(idNumber) {
		return o.GetCheckDigit() == idNumber[len(idNumber)-1:]
	} else {
		return regexp.MustCompile(ID_NUMBER_15_REGEX).MatchString(idNumber)
	}
} //校验身份证是否正确
func (o *IdNumber) GenerateId(sex int) string {

	//随机生成一个区域码(6位数)
	//id_number = str(random.choice(list(const.AREA_INFO.keys())))
	id_number := "410100"
	//限定出生日期范围(8位数)
	//start, end = datetime.strptime("1920-01-01", "%Y-%m-%d"), datetime.strptime("1930-12-30", "%Y-%m-%d")
	//birth_days = datetime.strftime(start + timedelta(random.randint(0, (end - start).days + 1)), "%Y%m%d")
	//id_number += str(birth_days)
	id_number += "19800101"
	// 顺序码(2位数)

	id_number += fmt.Sprintf(`%d`, 10+rand.Intn(99-10))

	// 性别码(1位数)
	//id_number += str(random.randrange(sex, 10, step=2))
	id_number += fmt.Sprintf(`%d`, rand.Intn(10))
	// 校验码(1位数)
	return id_number + o.GetCheckDigit()

} //随机生成身份证号，sex = 0表示女性，sex = 1表示男性
